package chen.web.user;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public final class Password implements Serializable{

	private static final long serialVersionUID = -8900984445740453862L;
	private String ciphertext;
	private String salt;
	
	public Password(String password){
		if(password == null || password.length() == 0){
			throw new IllegalArgumentException();
		}
		this.salt = salt();
		this.ciphertext = encrypt(password, salt);
	}
	
	public Password(String ciphertext, String salt){
		if(ciphertext == null || salt == null || ciphertext.length() == 0 || salt.length() == 0){
			throw new IllegalArgumentException();
		}
		this.salt = salt;
		this.ciphertext = ciphertext;
	}
	
	public boolean check(String password){
		String ciphertext = encrypt(password, salt);
		if(ciphertext.equals(this.ciphertext)){
			return true;
		}
		return false;
	}
	
	/**
	 * 生成盐
	 * @return	盐	
	 */
	private String salt(){
		Random rand=new Random();
		byte[ ] bsalt=new byte[12];
		rand.nextBytes(bsalt);
		
		String salt = null;
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<bsalt.length; i++){
			sb.append(bsalt[i] + ",");
		}
		salt = sb.toString();
		salt = salt.substring(0, salt.length() - 1);
		return salt;
	}
	
	/**
	 * MD5加盐算法
	 * @param plaintext	明文
	 * @param salt		盐
	 * @return			密文
	 */
	private static String encrypt(String plaintext, String salt){
		String[] s = salt.split(",");
		byte[] bsalt = new byte[s.length];
		
		for(int i=0; i<s.length; i++){
			bsalt[i] = Byte.parseByte(s[i]);
		}
		
		MessageDigest md = null;
		
		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			throw new SecurityException(e);
		}
		
		md.update(bsalt);
		try {
			md.update(plaintext.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			throw new SecurityException(e);
		}
		byte[] b = md.digest();

		StringBuffer sb = new StringBuffer(32);
		for(int i=0; i<b.length; i++){
			sb.append(Integer.toHexString((0x000000ff & b[i]) | 0xffffff00).substring(6));
		}

		return sb.toString();
	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		Password p = null;
		if(obj instanceof Password){
			p = (Password) obj;
		}
		if(p != null){
			return ciphertext.equals(p.ciphertext) && salt.equals(p.salt);
		}
		return false;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return ciphertext.hashCode();
	}

	/**
	 * @return	密文
	 */
	public String getCiphertext(){
		return ciphertext;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return new StringBuffer().append(ciphertext)
								.append(':')
								.append(salt)
								.toString();
	}
	
}
